{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Mayavi on Jupyter\n",
    "\n",
    "Works with either `'ipy'`, `'itk'`, `'x3d'` or `'png'` modes.  The PNG mode embeds images in the notebook and relies on off-screen-rendering working correctly.  The `'ipy'` mode also relies on off-screen support but is the default and most powerful of the options.  It also does not require WebGL support in your browser.\n",
    "\n",
    "For the default `'ipy'` backend, one also requires to have `ipywidgets` and `ipyevents` installed.  You may do this as:\n",
    "\n",
    "```\n",
    "  $ pip install ipywidgets ipyevents\n",
    "  $ jupyter nbextension enable --py widgetsnbextension\n",
    "  $ jupyter nbextension enable --py ipyevents\n",
    "\n",
    "```\n",
    "Or use a suitable package manager.\n",
    "\n",
    "For [X3D](http://www.x3dom.org) output to be rendered one either needs to [install the nbextensions](http://jupyter-notebook.readthedocs.io/en/latest/examples/Notebook/Distributing%20Jupyter%20Extensions%20as%20Python%20Packages.html#Installation-of-Jupyter-Extensions) for mayavi as\n",
    "\n",
    "```\n",
    "   $ jupyter nbextension install --py mayavi --user\n",
    "```\n",
    "or requires an internet connection and your browser to support WebGL.\n",
    "\n",
    "As of Mayavi-4.8.0 we have a new backend that renders client-side called `'itk'`, this backend requires that you have the `itkwidgets` package installed.\n",
    "\n",
    "\n",
    "In this notebook we demonstrate the different backends. For the X3D output this notebook requires an internet connection."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from mayavi import mlab "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Always start with this.\n",
    "mlab.init_notebook() # Defaults to the 'ipy' backend"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "s = mlab.test_contour3d()\n",
    "scp = mlab.pipeline.scalar_cut_plane(s)\n",
    "s.module_manager.scalar_lut_manager.show_scalar_bar = True\n",
    "s"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Note that if all goes well, you should be able to interact with the above just as you would with a typical Mayavi UI widget.  You should be able to interact with the camera, with the cut plane widget and with the scalar bar.\n",
    "\n",
    "Note that you will need to create a new figure if you want a different visualization.  In the following we show the same figure as above, note that interacting with one will automatically update the other as they are the same figure."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "mlab.gcf()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Note that unlike the other backends, if you call `mlab.clf()`, it will clear all the widgets for that particular figure -- since they are all the same."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## itkwidgets backend\n",
    "\n",
    "This requires that you have `itkwidgets` installed and is entirely client-side so this can be a useful option when visualizing data remotely.\n",
    "\n",
    "This backend is used when you pass `'itk'` as the backend as follows:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "mlab.init_notebook('itk')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The behaviour is similar to the other backends except that once rendered, the rendering will not change automatically when you update the underlying Mayavi objects (as of Mayavi-4.8.0 and itkwidgets 0.32-0.33)."
   ]
  },
  {
   "cell_type": "raw",
   "metadata": {},
   "source": [
    "mlab.figure()\n",
    "s = mlab.test_plot3d()\n",
    "s"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### X3D backend\n",
    "\n",
    "When initializing the notebook, use the x3d backend.  This backend embeds an X3D element into the notebook."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "mlab.init_notebook(backend='x3d', local=False) \n",
    "# local=True is the default but requires the nbextension to be installed.  \n",
    "# local=False pulls the content from the internet."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "mlab.figure()\n",
    "# Note the use of the figure here to create a new visualization.\n",
    "s = mlab.test_points3d()\n",
    "s"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "To see how to interact with the scene, please see: http://www.x3dom.org/documentation/interaction/\n",
    "\n",
    "- Left click and drag to rotate the camera.\n",
    "- Press 'r' or 'a' to reset the zoom.\n",
    "\n",
    "Most [modern browsers](http://www.x3dom.org/contact/) should be supported."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "mlab.clf()\n",
    "mlab.test_contour_surf()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### More examples\n",
    "\n",
    "Try the following examples too!\n",
    "\n",
    "Note that one can call `init_notebook` multiple times if needed."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "mlab.clf()\n",
    "s = mlab.test_mesh_sphere()\n",
    "s.actor.property.representation = 'wireframe'\n",
    "s"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "mlab.init_notebook('png') # This may not work well if off screen rendering is not working."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "mlab.clf()\n",
    "mlab.test_contour3d()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "mlab.init_notebook('x3d')\n",
    "mlab.clf()\n",
    "mlab.test_barchart()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.13"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
